 /*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

 /**
 * Project  : EasyAvatar-Lib
 * Package  : net.solosky.easyavatar.api.impl
 * File     : QQFriendProvider.java
 * Author   : solosky < solosky772@qq.com >
 * Created  : Oct 29, 2011
 * License  : Apache License 2.0 
 */
package net.solosky.easyavatar.api.impl;

import java.io.IOException;
import java.util.HashMap;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import net.solosky.easyavatar.api.ApiException;
import net.solosky.easyavatar.api.Avatar;
import net.solosky.easyavatar.api.ErrorCode;
import net.solosky.easyavatar.api.Group;
import net.solosky.easyavatar.api.Avatar.Scale;
import net.solosky.easyavatar.api.Friend;
import net.solosky.easyavatar.api.FriendList;
import net.solosky.easyavatar.api.http.HttpRequest;
import net.solosky.easyavatar.api.http.HttpResponse;

/**
 *
 * QQ好友提供者
 * 使用http://id.qq.com的接口
 *
 * @author solosky <solosky772@qq.com>
 *
 */
public class QQFriendProvider extends AbstractQQServiceFriendProvider {
	private static final String URL_MYFRIENDS = "http://id.qq.com/cgi-bin/friends_home";
	private static final String URL_BASE_KEY  = "http://id.qq.com/cgi-bin/get_base_key";
	private static final String URL_GET_INFO  = "http://id.qq.com/cgi-bin/info";
	private static final String URL_REMARK    = "http://id.qq.com/cgi-bin/remark";
	private static final String URL_MAYKNOWNS = "http://id.qq.com/cgi-bin/possible";
	private static final String URL_RICH_INFO = "http://id.qq.com/cgi-bin/richinfo";
	private static final String URL_AVATAR    = "http://id.qq.com/cgi-bin/face?u=%s"; 
	
	

	@Override
	public void signIn(String username, String password, String verifycode)
			throws ApiException, IOException {
		
		super.signIn(username, password, verifycode);
		
		//登录成功之后还需要获取LDW，不知道啥东东
		HttpRequest req = createHttpRequest(URL_BASE_KEY, "GET");
		req.addGetValue("r", Math.random()+"");
		HttpResponse res = executeHttpRequest(req);
		validateResponse(res);
		System.out.println(res.getResponseString());
	}

	@Override
	public void init() throws ApiException, IOException {
	}

	@Override
	public FriendList retireMyFriends(String index) throws ApiException,
			IOException {
		HttpRequest  req = createHttpRequest(URL_MYFRIENDS, "POST");
		req.addPostValue("ver", "20100914");
		HttpResponse res = executeHttpRequest(req);
		validateResponse(res);
		try {
			JSONObject json = new JSONObject(res.getResponseString());
			HashMap<String, Friend> friendMap = new HashMap<String, Friend>();
			FriendList friendList = new FriendList();
			friendList.setHasGroup(true);
			friendList.setHasNext(false);
			friendList.setNextIndex(null);
			
			JSONArray groups = json.getJSONArray("ginfo");
			for(int i=0; i<groups.length(); i++){
				JSONObject entry = groups.getJSONObject(i);
				Group group = new Group();
				group.setGid(entry.getString("gi"));
				group.setName(entry.getString("gn"));
				friendList.getGroups().add(group);
			}
			
			JSONArray friends = json.getJSONArray("finfo");
			for(int i=0; i<friends.length(); i++){
				JSONObject entry = friends.getJSONObject(i);
				Friend friend = new Friend();
				friend.setFid(entry.optString("u"));
				friend.setGid(entry.optString("g"));
				
				friendList.getFriends().add(friend);
				friendMap.put(friend.getFid(), friend);
			}
			
			//获取好友名字，每次获取200个，这个太蛋疼了。。。。。
			StringBuffer buffer = new StringBuffer(); 
			for(int i=0; i<friendList.getFriends().size(); i++){
				Friend friend = friendList.getFriends().get(i);
				buffer.append(friend.getFid());
				if( ((i+1)%200==0) || i==(friendList.getFriends().size()-1)){
					req = createHttpRequest(URL_GET_INFO, "POST");
					req.addPostValue("u", buffer.toString());
					req.addPostValue("t", System.currentTimeMillis()/1000+"");
					req.addPostValue("k", "");
					req.addPostValue("ldw", getLdw());
					res = executeHttpRequest(req);
					validateResponse(res);
					json = new JSONObject(res.getResponseString());
					friends = json.getJSONArray("ls");
					for(int j=0; j<friends.length(); j++){
						JSONObject entry = friends.getJSONObject(j);
						friend = friendMap.get(entry.optString("u"));
						friend.setNick(entry.optString("n"));
					}
					buffer = new StringBuffer();
					continue;
				}
				
				if(i<friendList.getFriends().size()-1){
					buffer.append("-");
				}
			}
			
			//获取设置的备注
			req = createHttpRequest(URL_REMARK, "POST");
			res = executeHttpRequest(req);
			validateResponse(res);
			json = new JSONObject(res.getResponseString());
			JSONArray remarks = json.getJSONArray("ls");
			for(int i=0; i<remarks.length(); i++){
				JSONObject entry = remarks.getJSONObject(i);
				Friend friend = friendMap.get(entry.getString("u"));
				friend.setName(entry.getString("r"));
			}
			
			return friendList;
			
		} catch (JSONException e) {
			throw new ApiException(ErrorCode.INVALID_RESPONSE, e);
		}
	}

	@Override
	public FriendList retireMayKnowns(String index) throws ApiException,
			IOException {
		HttpRequest  req = createHttpRequest(URL_MAYKNOWNS, "POST");
		req.addPostValue("t", System.currentTimeMillis()/1000+"");
		req.addPostValue("ldw", getLdw());
		HttpResponse res = executeHttpRequest(req);
		
		try {
			JSONObject json = new JSONObject(res.getResponseString());
			HashMap<String, Friend> friendMap = new HashMap<String, Friend>();
			FriendList friendList = new FriendList();
			friendList.setHasGroup(false);
			friendList.setHasNext(false);
			friendList.setNextIndex(null);
			JSONArray mayKnowns = json.getJSONArray("ls");
			for(int i=0; i<mayKnowns.length(); i++){
				JSONObject entry = mayKnowns.getJSONObject(i);
				Friend friend = new Friend();
				friend.setFid(entry.getString("u"));
				friendMap.put(friend.getFid(), friend);
				friendList.getFriends().add(friend);
			}
			
			//获取好友名字，最多200个。。
			StringBuffer buffer = new StringBuffer(); 
			for(int i=0; i<friendList.getFriends().size(); i++){
				Friend friend = friendList.getFriends().get(i);
				buffer.append(friend.getFid());
				if( ((i+1)%200==0) || i==(friendList.getFriends().size()-1)){
					req = createHttpRequest(URL_RICH_INFO, "POST");
					req.addPostValue("u", buffer.toString());
					req.addPostValue("t", "4");
					req.addPostValue("ldw", getLdw());
					res = executeHttpRequest(req);
					validateResponse(res);
					json = new JSONObject(res.getResponseString());
					JSONArray friends = json.getJSONArray("ls");
					for(int j=0; j<friends.length(); j++){
						JSONObject entry = friends.getJSONObject(j);
						friend = friendMap.get(entry.optString("u"));
						friend.setNick(entry.optString("nick"));
					}
					buffer = new StringBuffer();
					continue;
				}
				
				if(i<friendList.getFriends().size()-1){
					buffer.append("-");
				}
			}
			
			return friendList;
		} catch (JSONException e) {
			throw new ApiException(ErrorCode.INVALID_RESPONSE, e);
		}
		
	}

	@Override
	public Avatar retireFriendAvatar(Friend friend, Scale scale)
			throws ApiException, IOException {
		HttpRequest req = createHttpRequest(String.format(URL_AVATAR, friend.getFid()), "GET");
		HttpResponse res = executeHttpRequest(req);
		if(res.getResponseCode()==HttpResponse.HTTP_OK){
			friend.getAvatar().setData(res.getResponseData());
			friend.getAvatar().setUrl(req.getUrl());
			return friend.getAvatar();
		}else{
			throw new ApiException(ErrorCode.NO_AVATAR);
		}
	}

	@Override
	public Avatar retireMyAvatar(Friend friend, Scale scale)
			throws ApiException, IOException {
		return retireFriendAvatar(friend, scale);
	}

	@Override
	public Friend retireMyInfo() throws ApiException, IOException {
		HttpRequest req = createHttpRequest(URL_GET_INFO, "POST");
		req.addPostValue("u", getUin());
		req.addPostValue("t", System.currentTimeMillis()/1000+"");
		//req.addPostValue("c", "1");
		HttpResponse res = executeHttpRequest(req);
		validateResponse(res);
		try {
			JSONObject json = new JSONObject(res.getResponseString());
			JSONObject entry = json.getJSONArray("ls").getJSONObject(0);
			Friend friend = new Friend();
			friend.setFid(entry.getString("u"));
			friend.setNick(entry.getString("n"));
			friend.setName(entry.getString("p"));
			return friend;
		} catch (JSONException e) {
			throw new ApiException(ErrorCode.INVALID_RESPONSE, e);
		}
	}

	@Override
	protected String getAppId() {
		return "1006102";
	}
	
	private String getLdw(){
		return getHttpClient().getCookie("ldw").getValue();
	}

}
